home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / ddj0492.zip / HANDPRIN.URC / Recognizer / RecognizerUtil.c < prev    next >
Text File  |  1992-03-11  |  9KB  |  386 lines

  1. /* All rights reserved. Copyright Ron Avitzur - 1992
  2. */
  3.  
  4. #define DOT_THRESHHOLD            (Wacom?80:4)
  5. #define PT_SEP_POST             (Wacom?40:4)
  6. #define PT_SEP_POST_RATIO_X     8
  7. #define PT_SEP_POST_RATIO_Y     8
  8.  
  9. #include "Recognizer.h"
  10.  
  11. List patterns = NIL;
  12. short Dont_Use_Table = TRUE;
  13. short Wacom;
  14. TABLETRECORD *TRecord;
  15. int dummies[40];
  16. long ScreenYSize,TabYSize,TabYMin,ScreenXSize,TabXSize,TabXMin;
  17. AVList HashList[NUM_HASHLISTS]; /* Assumed all initialized to NIL */
  18. short TRAINING_TIME_OUT = 10,min_weight = 0;
  19. short Training = FALSE;
  20. Rect BBox;
  21. short PauseIsMouse = FALSE;
  22. short RecognizeWords = FALSE;
  23.  
  24. char **free_list = NIL;
  25. #if 0
  26. char *mycalloc(short n,long size);
  27. char *mycalloc(short n,long size)
  28.     {
  29.     if (free_list == NIL)
  30.         return calloc(n,size);
  31.     else {
  32.         char *ret_val = (char*)free_list;
  33.         free_list = (char**)*free_list;
  34.         return ret_val;
  35.         }        
  36.     }
  37.  
  38. void myfree(char *p);
  39. void myfree(char *p)
  40.     {
  41.     *(char**)p = (char*)free_list;
  42.     free_list = p;    
  43.     }
  44. #endif
  45.  
  46. void FreeStrokes() {
  47.     short i;
  48.      if (Strokes) {
  49.          for (i = 0; i < Strokes->num_items; i++) {
  50.              StrokePtr sp = Strokes->items[i];
  51.              if (sp->matches)
  52.                  free(sp->matches);
  53.              free(sp);
  54.              }
  55.          free(Strokes);
  56.          }
  57.      Strokes = NIL;
  58.     }
  59.  
  60. void DisposePatterns() {
  61.     short i,j,k;
  62.     if (patterns) for (i = 0; i < patterns->num_items; i++) {
  63.         GesturePattern *gp = patterns->items[i];
  64.         if (gp->strokes) for (j = 0; j < gp->strokes->num_items; j++) {
  65.             StrokePattern *sp = gp->strokes->items[j];
  66.             for (k = 0; k < NUM_FEATURES; k++) if (sp->s[k]) free(sp->s[k]);
  67.             free(sp);
  68.             }
  69.         free(gp);
  70.         }
  71.     patterns = NIL;
  72.     }
  73.  
  74. void Append(List *theList,long item)
  75.     {
  76.     if (*theList == NULL) {
  77.         *theList = malloc(sizeof(List) + sizeof(long));
  78.         (*theList)->num_items = 1;
  79.         (*theList)->items[0] = (void*)item;
  80.         }
  81.     else {
  82.         (*theList)->num_items += 1;
  83.         *theList = realloc(*theList,sizeof(List) + (*theList)->num_items*sizeof(long));
  84.         (*theList)->items[(*theList)->num_items-1] = (void*)item;
  85.         }
  86.     }
  87.  
  88. void AppendAVPair(AVList *theList,AVPair item)
  89.     {
  90.     if (*theList == NULL) {
  91.         *theList = malloc(sizeof(AVList) + sizeof(AVPair));
  92.         (*theList)->num_items = 1;
  93.         (*theList)->items[0] = item;
  94.         }
  95.     else {
  96.         (*theList)->num_items += 1;
  97.         *theList = realloc(*theList,sizeof(List) + (*theList)->num_items*sizeof(AVPair));
  98.         (*theList)->items[(*theList)->num_items-1] = item;
  99.         }
  100.     }
  101.  
  102. static int Compare(AVPair *a,AVPair *b);
  103. static int Compare(AVPair *a, AVPair *b)
  104.     {
  105.     if (a->index > b->index) return 1;
  106.     if (a->index < b->index) return -1;
  107.     return 0;
  108.     }
  109.  
  110. void SearchAndAddMatches(short *possibles,short *weights,short *npossibles,
  111.                                 AVList theList,register unsigned long n,short w)
  112.     {
  113.     if (theList)
  114.         {
  115.         short where;
  116.         register AVPair *items = theList->items,*guess;
  117.         AVPair key;
  118.         key.index = n;
  119.  
  120.         guess = bsearch(&key,items,theList->num_items,sizeof(AVPair),(void*)Compare);
  121.         if (guess == NULL) return;
  122.         where = guess - items;
  123.         while (where > 0 && n == items[where-1].index) where--;
  124.         while (where < theList->num_items && n == items[where].index) {
  125.             register short i, code = items[where].code;
  126.             for (i = 0; i < *npossibles; i++) {
  127.                 if (possibles[i] == code) {
  128.                     weights[i] += w;
  129.                     goto NEXT_CODE;
  130.                     }
  131.                 }
  132.             possibles[*npossibles] = code;
  133.             weights[*npossibles]   = w;
  134.             (*npossibles)++;
  135.             NEXT_CODE:
  136.             where++;
  137.             }
  138.         }
  139.     }
  140.  
  141. void MakeSearchTables()
  142.     {
  143.     short i,j,k;
  144.     GesturePattern *gp;
  145.     StrokePattern    *sp;
  146.     AVPair item;
  147.     
  148.     for (i=0;i<NUM_HASHLISTS;i++) if (HashList[i]) { free(HashList[i]); HashList[i] = NIL; }
  149.     for (i = 0; i < patterns->num_items; i++) {
  150.         gp = patterns->items[i];
  151.         sp = gp->strokes->items[0];
  152.         for (k=0;k<NUM_HASHLISTS;k++)
  153.             if (sp->s[k]) for (j = 0; j < sp->s[k]->num_items; j++) {
  154.                 item.index = (long)sp->s[k]->items[j];
  155.                 item.code  = i;
  156.                 AppendAVPair(&HashList[k],item);
  157.                 }
  158.         }
  159.  
  160.     /* Sort Tables numerically by index values */
  161.     for (i=0;i<NUM_HASHLISTS;i++) 
  162.         qsort(HashList[i]->items,HashList[i]->num_items,sizeof(AVPair),(void*)Compare);
  163.     Dont_Use_Table = FALSE;
  164.     }
  165.  
  166. short ATAN2_TABLE[21][21];
  167. short ATAN2(register short dy,register short dx)
  168.     {
  169.     while (dx > 10 || dx < -10 || dy > 10 || dy < -10)
  170.         { dx >>= 2; dy >>= 2; }
  171.     return ATAN2_TABLE[dy + 10][dx + 10];
  172.     }
  173.  
  174. void RecognizerInit()
  175.     {
  176.     int Ref;
  177.     long count;
  178.     short i,j;
  179.     double r2d;
  180.     OSErr err;
  181.     err = OpenDriver("\p.Wacom",&Ref);
  182.     Wacom = (err == noErr);
  183.     if (Wacom) err = Status(Ref,GET_RECORD,&TRecord);
  184.     Wacom = (err == noErr);
  185.     if (Wacom) if (TRecord->tabletID != 'TBLT') Wacom = 0;
  186.  
  187.     r2d = 180 / 3.141592654;
  188.     for (i = 0; i <= 10; i++)
  189.         for (j = 0; j <= 10; j++) {
  190.             short t = r2d * atan2(i,j);
  191.             ATAN2_TABLE[ i + 10][ j + 10] =  t;
  192.             ATAN2_TABLE[-i + 10][ j + 10] = -t;
  193.             ATAN2_TABLE[ i + 10][-j + 10] = 180 - t;
  194.             ATAN2_TABLE[-i + 10][-j + 10] = t - 180;
  195.             }
  196.     SetupMapping();
  197.     }
  198.  
  199. void SetupMapping()
  200.     {
  201.     if (Wacom) {
  202.         ScreenYSize    = TRecord->screenYMax-TRecord->screenYMin;
  203.         TabYSize        = TRecord->tabYMax-TRecord->tabYMin;
  204.         TabYMin        = TRecord->tabYMin;
  205.         ScreenXSize    = TRecord->screenXMax-TRecord->screenXMin;
  206.         TabXSize        = TRecord->tabXMax-TRecord->tabXMin;
  207.         TabXMin        = TRecord->tabXMin;
  208.         }
  209.     else {
  210.         ScreenYSize    = 1;
  211.         TabYSize        = 1;
  212.         TabYMin        = 0;
  213.         ScreenXSize    = 1;
  214.         TabXSize        = 1;
  215.         TabXMin        = 0;
  216.         }
  217.     }
  218.  
  219. List Strokes = NIL;
  220. StrokePtr The_Stroke;
  221. char *FastString = "0123456789+-=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  222. NamedCode Commands[] = {
  223. "\Pdelete",        8,
  224. "\Pspace",        32,
  225. "\P<<--",        r_MOVELEFTINTO,
  226. "\P<-",            r_MOVELEFT,
  227. "\P->",            r_MOVERIGHT,
  228. "\P-->>",        r_MOVERIGHTINTO,
  229. "\Pup",            r_MOVEUP,
  230. "\Pdown",        r_MOVEDOWN,
  231. "\Pisolate",    r_SOLVEFOR,
  232. "\Psimplify",    r_SIMPLIFY,
  233. "\pdot",            DOT_OP,
  234. "\Pvector",        d_VECTOR,
  235. "\pderiv",        o_PARTIAL,
  236. "\Pdiff.",        r_DIFFERENTIATE,
  237. "\p=eval",        r_COPYPASTECRUNCH,
  238. "\ptrig2exp",    r_TRIGTOEXPONENTS,
  239. "\pvec2mat",    r_VECTORSTOMATRICES,
  240. "\ptaylor",        r_TAYLOREXPAND,
  241. "\pmatrix",        r_MATRIXALGEBRA,
  242. "\ppull one",    r_PULLOUTONETERM,
  243. "\pintegrate",    r_INTEGRATE,
  244. "\pintegral",    INTEGRAL_OP
  245. };
  246. short Num_Commands = sizeof(Commands) / sizeof(Commands[0]);
  247.  
  248. short Learn_Code;
  249. short Current_Pattern = -1;
  250.  
  251. void Set_Current_Pattern()
  252.     {
  253.     short i;
  254.     Current_Pattern = -1;
  255.     if (patterns)
  256.     for (i = 0; i < patterns->num_items; i++) {
  257.         GesturePattern *gp = patterns->items[i];
  258.         if (gp->code == Learn_Code) {
  259.             Current_Pattern = i;
  260.             return;
  261.             }
  262.         }
  263.     }
  264.  
  265.  
  266. short NumSymbols(void)
  267.     {
  268.     return strlen(FastString) + NUM_GREEK + Num_Commands;
  269.     }
  270.  
  271. short Code(short n)
  272.     {
  273.     short len = strlen(FastString);
  274.     if (n < len)                        return FastString[n];
  275.     else if (n < len + NUM_GREEK)    return 0x1300 + n - len;
  276.     else return Commands[n - len - NUM_GREEK].code;
  277.     }
  278.  
  279. short FindCode(short code)
  280.     {
  281.     short i,len = strlen(FastString);
  282.     for (i = 0; i < len; i++)
  283.         if (code == FastString[i])
  284.             return i;
  285.     for (i = len; i < len + NUM_GREEK; i++)
  286.         if (code == 0x1300 + i - len)
  287.             return i;
  288.     for (i = len + NUM_GREEK; i < NumSymbols(); i++)
  289.         if (code == Commands[i - len - NUM_GREEK].code)
  290.             return i;
  291.     return -1;
  292.     }
  293.  
  294.  
  295. void ExtendRange()
  296.     {
  297.     short i,j;
  298.     GesturePattern *gp;
  299.     StrokePattern  *sp;
  300.     StrokePtr        theStroke;
  301.     if (Current_Pattern == -1) { AddNewPattern(); return; }
  302.     if (Strokes == NIL) return;
  303.  
  304.     gp = patterns->items[Current_Pattern];
  305.     if (gp->strokes->num_items != Strokes->num_items) {
  306.         short code = gp->code;
  307.         for (i = 0; i < patterns->num_items; i++) {
  308.             gp = patterns->items[i];
  309.             if (gp->code == code && gp->strokes->num_items == Strokes->num_items)
  310.                 goto GO_ON;
  311.             }
  312.         AddNewPattern();
  313.         return;
  314.         }
  315. GO_ON:
  316.     for (i = 0; i < Strokes->num_items; i++) {
  317.         sp = gp->strokes->items[i];
  318.         theStroke = Strokes->items[i];
  319.         for (j=0;j<NUM_FEATURES;j++)
  320.             if (!IsInList(sp->s[j],theStroke->S[j]))
  321.                 Append(&sp->s[j],theStroke->S[j]);
  322.         }
  323.     Dont_Use_Table = TRUE;
  324.     }
  325.  
  326. void AddNewPattern()
  327.     {
  328.     short i,j;
  329.  
  330.     GesturePattern *gp;
  331.     StrokePattern  *sp;
  332.     StrokePtr        theStroke;
  333.  
  334.     if (Strokes == NIL) return;
  335.     gp = malloc(sizeof(GesturePattern));
  336.     if (gp == NIL) {SysBeep(1); Debugger(); ExitToShell();}
  337.  
  338.     gp->code = Learn_Code;
  339.     gp->strokes = NIL;
  340.  
  341.     for (i = 0; i < Strokes->num_items; i++) {
  342.         sp = malloc(sizeof(StrokePattern));
  343.         if (sp == NIL) {SysBeep(1); Debugger(); ExitToShell();}
  344.         theStroke = Strokes->items[i];
  345.     
  346.         sp->is_dot = theStroke->IsDot;
  347.         for (j=0;j<NUM_FEATURES;j++) { sp->s[j] = NIL; Append(&sp->s[j],theStroke->S[j]); }
  348.         Append(&gp->strokes,(long)sp);
  349.         }
  350.  
  351.     Append(&patterns,(long)gp);
  352.     Dont_Use_Table = TRUE;
  353.     }
  354.  
  355. void ConvertStringToLong(char *s,unsigned long *np,short bits)
  356.     {
  357.     unsigned long n = 0;
  358.     short i,len = strlen(s);
  359.     s[len] = s[len-1];
  360.     if (len > 32/bits) len = 32/bits;
  361.     for (i = 0; i <= len; i++)
  362.         n = (n << bits) + s[len - i] - '0';
  363.     *np = n;
  364.     }
  365.  
  366. void ConvertLongToString(s,n,bits,name)
  367.  char *s;
  368.  unsigned long n;
  369.  short bits;
  370.  char *name;
  371.     {
  372.     short i = 0, max_len = 32/bits;
  373.     unsigned long mask = (1<<bits)-1;
  374.     if (!name) name = "0123456789abcdef";
  375.     do {
  376.         s[i++] = name[n & mask];
  377.         n = n>>bits;
  378.         }
  379.     while (i < max_len && (i == 1 || s[i - 1] != s[i - 2]));
  380.     if (i != max_len || s[i - 1] == s[i - 2])
  381.             s[i - 1] = 0;
  382.     else    s[i] = 0;
  383.     }
  384.  
  385.  
  386.